﻿using System.Collections.Generic;
using System.Drawing;
namespace System.Windows.Forms
{
    public partial class ImageView : UserControl
    {
        #region 属性
        private Image _Image;
        public Image Image
        {
            get
            {
                return _Image;
            }
            set
            {
                if (value != null)
                {
                    this._Image = value;
                    viewpanel.Size = this._Image.Size;
                    imagew = viewpanel.Size.Width;
                    imageh = viewpanel.Size.Height;
                    graphicsbmp = new Bitmap(imagew, imageh);
                    showinfo(string.Format("size:{0}x{1};dpi:{2}", this._Image.Width, this._Image.Height, _Image.VerticalResolution));

                    viewpanel_BackgroundImageChanged(null, null);
                    SetImageLocation();
                }
            }
        }

        public float ImageScale { get; set; }
        private int imagew { get; set; }
        private int imageh { get; set; }
        private int graphicsw { get; set; }
        private int graphicsh { get; set; }

        private Bitmap graphicsbmp = null;
        #endregion
        /// <summary>
        /// 设置控件DoubleBuffered缓冲设置
        /// </summary>
        /// <param name="control"></param>
        private void setDoubleBuffered(Control control)
        {
            if (control != null)
            {
                Type controlType = control.GetType();
                System.Reflection.PropertyInfo pi = controlType.GetProperty("DoubleBuffered", System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.NonPublic);
                pi.SetValue(control, true, null);
            }
        }
        /// <summary>
        /// 初始化
        /// </summary>
        public ImageView()
        {
            InitializeComponent();
            Application.EnableVisualStyles();
            SetStyle(ControlStyles.AllPaintingInWmPaint, true);//防止重回窗体出现闪烁
            SetStyle(ControlStyles.OptimizedDoubleBuffer, true);//防止重回窗体出现闪烁
            SetStyle(ControlStyles.UserPaint, true);
            this.DoubleBuffered = true;
            setDoubleBuffered(viewpanel);
            setDoubleBuffered(panelparent);
            this.UpdateStyles();

            this.viewpanel.MouseDown += new System.Windows.Forms.MouseEventHandler(this.viewpanel_MouseDown);
            this.viewpanel.MouseUp += new System.Windows.Forms.MouseEventHandler(this.viewpanel_MouseUp);
            this.viewpanel.MouseMove += new System.Windows.Forms.MouseEventHandler(this.viewpanel_MouseMove);
            viewpanel.MouseWheel += viewpanel_MouseWheel;
            this.MouseWheel += viewpanel_MouseWheel;

            

        }

        protected override void OnBackColorChanged(EventArgs e)
        {
            base.OnBackColorChanged(e);
            panelparent.BackColor = this.BackColor;
        }


        List<Point> points = new List<Point>();


        private void viewpanel_MouseWheel(object sender, MouseEventArgs e)
        {
            try
            {
                if (e.Delta > 0)
                {
                    ZoomIn();
                }
                else
                {
                    ZoomOut();
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
            }
        }
        private void viewpanel_BackgroundImageChanged(object sender, EventArgs e)
        {
            if (Image == null) return;
            int maxpictureBox = Math.Max(viewpanel.Width, viewpanel.Height);
            int minviewpanel = Math.Min(this.Width, this.Height);

            if (maxpictureBox > minviewpanel)
            {
                ImageScale = minviewpanel / (float)maxpictureBox;
            }
            else
            {
                ImageScale = 1.0f;
            }
            Zoom(ImageScale);
        }
        /// <summary>
        /// 居中显示
        /// </summary>
        private void SetImageLocation()
        {
            if (Image == null) return;
            try
            {
                Point newPoint = new Point();

                int maxviewpanel = Math.Max(viewpanel.Width, viewpanel.Height);
                int minviewpanel = Math.Min(this.Width, this.Height);

                if (maxviewpanel <= minviewpanel)
                {
                    newPoint.X = System.Convert.ToInt32((panelparent.Width - viewpanel.Width) * 0.5);
                    newPoint.Y = System.Convert.ToInt32((panelparent.Height - viewpanel.Height) * 0.5);
                    viewpanel.Location = newPoint;
                }
                else
                {
                    newPoint.X = System.Convert.ToInt32((panelparent.Width - viewpanel.Width) * 0.5);
                    newPoint.Y = System.Convert.ToInt32((panelparent.Height - viewpanel.Height) * 0.5);
                    viewpanel.Location = newPoint;
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
            }
        }

        #region 公开方法
        /// <summary>
        /// 放大 
        /// </summary>
        public void ZoomIn()
        {
            Zoom(1.25f);
        }

        /// <summary>
        /// 缩小 
        /// </summary>
        public void ZoomOut()
        {
            Zoom(0.8f);
        }
        /// <summary>
        /// 缩放
        /// </summary>
        /// <param name="scale"></param>
        public void Zoom(float scale = 1.0f)
        {
            if (Image == null) return;
            try
            {
                int newWidth = System.Convert.ToInt32(viewpanel.Width * scale);
                int newHeight = System.Convert.ToInt32(viewpanel.Height * scale);

                Rectangle rectangle = Screen.PrimaryScreen.Bounds;
                double workWidth = rectangle.Width; // 屏幕工作区域宽度
                double workHeight = rectangle.Height; // 屏幕工作区域高度
                if (newWidth >= workWidth * 15 || newHeight >= workHeight * 15)
                {
                    // viewpanel.Visible = false;
                    //viewpanel.Size = new System.Drawing.Size(newWidth, newHeight);
                    //Bitmap bmp = new Bitmap(this.panelparent.Width, this.panelparent.Height);
                    //Graphics g = Graphics.FromImage(bmp);
                    //g.Clear(Color.White);
                    //Rectangle rect = new Rectangle(0, 0, bmp.Width, bmp.Height);
                    //g.DrawImage(this.Image, rect, rect, GraphicsUnit.Pixel);
                    //bmp.SetResolution(400, 400);
                    //viewpanel.BackgroundImage = bmp;
                    //Graphics g = Graphics.FromHwnd(viewpanel.Handle);
                    //g.Clear(Color.White);
                    //int k = 1;
                    //int w = (this.panelparent.Width / k) - 1;
                    //int h = (this.panelparent.Height / k) - 1;
                    //for (int i = 0; i < w; i++)
                    //{
                    //    for (int j = 0; j < h; j++)
                    //    {
                    //        g.FillRectangle(new SolidBrush(((Bitmap)this.Image).GetPixel(i, j)), i * k, j * k, k, k);
                    //    }
                    //}

                }
                else
                {
                    viewpanel.BackgroundImage = this.Image;
                    viewpanel.Size = new System.Drawing.Size(newWidth, newHeight);
                    viewpanel.Visible = true;
                }

                this.panelBom.Visible = (viewpanel.Width >= this.panelparent.Width);
                if (this.panelBom.Visible)
                {
                    this.hScrollBar.Value = 0;
                }
                this.panelRight.Visible = (viewpanel.Height >= this.panelparent.Height);
                if (this.panelRight.Visible)
                {
                    this.vScrollBar.Value = 0;
                }
                ImageScale = scale;
                SetImageLocation();
            }
            catch (Exception ex)
            {
                return;
            }
        }
        /// <summary>
        /// 旋转 
        /// </summary>
        public void Rotation(int deg = 90)
        {
            if (Image == null) return;
            if (viewpanel.BackgroundImage == null) return;
            if (deg == 0) return;
            if (deg == 90)
            {
                Image.RotateFlip(RotateFlipType.Rotate90FlipNone);
            }
            else
            {
                Image.RotateFlip(RotateFlipType.Rotate270FlipNone);
            }
            this.viewpanel.BackgroundImage = null;
            this.viewpanel.BackgroundImage = this.Image;
            int temp = viewpanel.Width;
            viewpanel.Width = viewpanel.Height;
            viewpanel.Height = temp;
            //Zoom(ImageScale);
            SetImageLocation();
        }
        #endregion


        #region 菜单

        private void contextMenuItemR_Click(object sender, EventArgs e)
        {
            Rotation(90);
        }
        private void contextMenuItemL_Click(object sender, EventArgs e)
        {
            Rotation(270);
        }
        private void MenuItemRotationR_Click(object sender, EventArgs e)
        {
            contextMenuItemR_Click(null, null);
        }

        private void MenuItemRotationL_Click(object sender, EventArgs e)
        {
            contextMenuItemL_Click(null, null);
        }

        private void MenuItemZoomIn_Click(object sender, EventArgs e)
        {
            ZoomIn();
        }

        private void MenuItemZoomOut_Click(object sender, EventArgs e)
        {
            ZoomOut();
        }
        #endregion
        private Point mouseleftdown;
        private void viewpanel_MouseMove(object sender, MouseEventArgs e)
        {
            if (e.Button != MouseButtons.Left) return;

            Point viewpaneloldLocation = viewpanel.Location;
            if ((viewpaneloldLocation.X < 0 || viewpaneloldLocation.Y <= 0))
                if (e.Button == MouseButtons.Left)
                {
                    if (this.vScrollBar.Visible || hScrollBar.Visible)
                    {
                        viewpaneloldLocation.Offset(e.X - mouseleftdown.X, e.Y - mouseleftdown.Y);
                        if (viewpaneloldLocation.X >= 0) viewpaneloldLocation.X = 0;
                        if (viewpaneloldLocation.Y >= 0) viewpaneloldLocation.Y = 0;
                        if (viewpaneloldLocation.X <= panelparent.Width - viewpanel.Width) viewpaneloldLocation.X = panelparent.Width - viewpanel.Width;
                        if (viewpaneloldLocation.Y <= panelparent.Height - viewpanel.Height) viewpaneloldLocation.Y = panelparent.Height - viewpanel.Height;
                        viewpanel.Location = viewpaneloldLocation;
                    }
                }


        }
        private void viewpanel_MouseDown(object sender, MouseEventArgs e)
        {
            if (e.Button == MouseButtons.Left)
            {
                mouseleftdown = e.Location;
                Cursor.Current = Cursors.Hand;
            }
        }
        private void viewpanel_MouseUp(object sender, MouseEventArgs e)
        {
            Cursor.Current = Cursors.Default;

        }
        private void ImageView_SizeChanged(object sender, EventArgs e)
        {
            viewpanel_BackgroundImageChanged(null, null);
        }
        /// <summary>
        /// 垂直滚动条
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void vScrollBar_ValueChanged(object sender, EventArgs e)
        {
            try
            {
                int mintop = (panelparent.Height - viewpanel.Height) / 2;
                int changed = (int)(vScrollBar.Value * 0.01 * (viewpanel.Height - panelparent.Height) * 0.5);
                this.viewpanel.Location = new Point(this.viewpanel.Location.X, mintop - changed);
            }
            catch (Exception)
            {
            }
        }
        /// <summary>
        /// 水平滚动条
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void hScrollBar_ValueChanged(object sender, EventArgs e)
        {
            try
            {
                int minleft = (panelparent.Width - viewpanel.Width) / 2;
                int changed = (int)(hScrollBar.Value * 0.01 * (viewpanel.Width - panelparent.Width) * 0.5);
                this.viewpanel.Location = new Point(minleft - changed, this.viewpanel.Location.Y);
            }
            catch (Exception)
            {
            }
        }
        private void showinfo(string info = "")
        {
            labelinfo.Text = info;
            panelBomLeft.Width = labelinfo.Width + 10;
        }

    }
}
